package com.qinggeng.project.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.qinggeng.common.enums.*;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.CalendarAdjustUtils;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.MessageGoodsRefundMessageDTO;
import com.qinggeng.framework.config.mq.dto.MessageOrderSingleltemDTO;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.project.api.dto.GiftReturn;
import com.qinggeng.project.api.dto.SingleItemRefundDTO;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.domain.vo.CourierRefundOrdersVO;
import com.qinggeng.project.system.domain.vo.ReturnOrdersGoodsVO;
import com.qinggeng.project.system.domain.vo.UserAccountRecordOrderSingleItemVO;
import com.qinggeng.project.system.dto.SysUserAccountRecordOrderSingleItemDTO;
import com.qinggeng.project.system.mapper.UserAccountRecordOrderSingleItemMapper;
import com.qinggeng.project.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class UserAccountRecordOrderSingleItemServiceImpl  implements UserAccountRecordOrderSingleItemService {
    @Resource
    private UserAccountRecordOrderSingleItemMapper userAccountRecordOrderSingleItemMapper;

    @Resource
    private IOrdersGoodsService ordersGoodsService;

    @Resource
    private IOrdersService ordersService;


    @Resource
    private MQSendUtils mqSendUtils;

    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Resource
    private TransactionDefinition transactionDefinition;

    @Autowired
    private IOrdersCourierService ordersCourierService;

    @Autowired
    private ISysUserService sysUserService;

    @Resource
    private UserAccountRecordOrderSingleItemService userAccountRecordOrderSingleItemService;
    @Autowired
    private SumPointSaleService sumPointSaleService;
    @Autowired
    private SinglePointSaleService singlePointSaleService;
    @Autowired
    private IUserAliasService userAliasService;
    @Autowired
    private MessagePushService messagePushService;
    @Autowired
    private IUserMessageService messageService;



    @Override
    public boolean insertUserAccountRecordOrderSingleItem(UserAccountRecordOrderSingleItem userAccountRecordOrderSingleItem) {
        Date date =new Date();
        userAccountRecordOrderSingleItem.setCreateDate(date);
        userAccountRecordOrderSingleItem.setCreateTime(date);
        userAccountRecordOrderSingleItem.setCreateYear(CalendarAdjustUtils.getYearToStr());
        userAccountRecordOrderSingleItem.setUpdateTime(date);
        userAccountRecordOrderSingleItem.setCreateMonth(CalendarAdjustUtils.getLastMonthToStr());
        userAccountRecordOrderSingleItem.setType(MQTypeEnum.SINGLE_LTEM_REFUND_ACCOUNT.getType());
        userAccountRecordOrderSingleItem.setSingleType(1);
        Instant instant = Instant.now();
        long timeStampMillis = instant.toEpochMilli();
        userAccountRecordOrderSingleItem.setCreateTimeStamp(timeStampMillis);
        boolean bl =userAccountRecordOrderSingleItemMapper.insertSelective(userAccountRecordOrderSingleItem)>=1;
        if (bl ==false){
            throw  new CustomException("单商品退款失败");
        }
        userAccountRecordOrderSingleItem.setId(null);
        return true;

    }

    @Override
    public UserAccountRecordOrderSingleItem checkUserAccountRecordOrderSingleItem(UserAccountRecordOrderSingleItem  single) {

        Long ordersGoodsId=single.getOrderGoodsId();

        UserAccountRecordOrderSingleItem singleItem= getUserAccountRecordOrderSingleItem(single);
        if (null == singleItem){
            insertUserAccountRecordOrderSingleItem(single);
            ordersGoodsService.sigleItemRefund(ordersGoodsId);
            return  single;
        }
        return singleItem;
    }

    @Override
    public UserAccountRecordOrderSingleItem getUserAccountRecordOrderSingleItem(UserAccountRecordOrderSingleItem userAccountRecordOrderSingleItem) {
        Example example=new Example(UserAccountRecordOrderSingleItem.class);
        Long userId=userAccountRecordOrderSingleItem.getUserId();
        if (null == userId){
            throw  new CustomException("userId is  null");
        }
        String  ordersNo=userAccountRecordOrderSingleItem.getOrderNo();
        if (StringUtils.isEmpty(ordersNo)){
            throw  new CustomException("orderNo is  null");
        }

        Long ordersGoodsId=userAccountRecordOrderSingleItem.getOrderGoodsId();
        if (null == ordersGoodsId){
            throw  new CustomException("orderGoodsId is  null");
        }
        example.createCriteria()
                .andEqualTo("userId",userId)
                .andEqualTo("status",0)
                .andEqualTo("ordersNo",ordersNo)
                .andEqualTo("orderGoodsId",ordersGoodsId)
                .andEqualTo("status",0)
                .andEqualTo("delFlag",0);
        return getUserAccountRecordOrderSingleItem(example);
    }

    @Override
    public boolean orderSingleItemRefund(SingleItemRefundDTO dto) {

        Long orderId=dto.getOrdersId();
        if (null ==orderId){
            throw  new CustomException("orderId不能为空");
        }

        Orders orders= ordersService.selectOrdersById(orderId);
        if (null ==orders){
            throw  new CustomException("订单不存在");
        }
        String ordersNo=orders.getOrdersNo();
        if (StringUtils.isEmpty(ordersNo)){
            throw  new CustomException("订单编号不能为空");
        }
        String orderType=orders.getOrdersType();
        log.info("单商品退款 {}  订单类型 {}",ordersNo,orderType);

        if (OrdersTypeEnum.代付.getValue().equals(orderType)){
            throw  new CustomException("代付订单退款，请联系客服");
        }
        String ordersGoodsIdsStr=dto.getOrderGoodsIds();
        String[]  ordersGoodsIds=ordersGoodsIdsStr.split(",");
        List<UserAccountRecordOrderSingleItem> items=new ArrayList<>();
        boolean bl=false;
        TransactionStatus transactionStatus=dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //订单退款
            BigDecimal sumMoney=BigDecimal.ZERO;
            for (String orderGoodsIdstr : ordersGoodsIds) {
                Long orderGoodsId=Long.valueOf(orderGoodsIdstr);
                bl=ordersGoodsService.sigleItemRefund(orderGoodsId);
                if (bl ==false){
                    throw  new CustomException("该状态不能申请退款");
                }
                UserAccountRecordOrderSingleItem item=checkUserAccountRecordOrderSingleItem(dto);
                if (ordersGoodsIds.length >=1){
                    item.setSingleType(1);
                }
                if (ordersGoodsIds.length <1){
                    item.setSingleType(0);
                }
                item.setUserName("");
                item.setType(MQTypeEnum.SINGLE_LTEM_REFUND_ACCOUNT.getType());
                item.setStatus(0);
                Date date =new Date();
                item.setCreateDate(date);
                item.setCreateTime(date);
                item.setCreateYear(CalendarAdjustUtils.getYearToStr());
                item.setUpdateTime(date);
                item.setCreateMonth(CalendarAdjustUtils.getMonthToStr());
                Instant instant = Instant.now();
                long timeStampMillis = instant.toEpochMilli();
                item.setCreateTimeStamp(timeStampMillis);
                item.setOrderNo(ordersNo);
                item.setOrderGoodsId(orderGoodsId);
                item.setDelFlag(0);

                Long userId=dto.getUserId();
                BigDecimal money=ordersGoodsService.calculation(orderGoodsId,userId);
                sumMoney=sumMoney.add(money);
                items.add(item);
            }
            String payment=dto.getPayment();

            if (new BigDecimal(payment).compareTo(sumMoney)>0){
                throw  new CustomException("退款金额不能超过商品金额");
            }

            bl=insertUserAccountRecordOrderSingleItems(items);
            if (bl ==false){
                throw  new CustomException("退款失败,稍后再试");
            }

            dataSourceTransactionManager.commit(transactionStatus);
            try {
                OrdersCourier ordersCourier = ordersCourierService.selectOrdersCourierByOrdersId(dto.getOrdersId());
                Long userId = sysUserService.selectUserIdByPhoneNumberAndUserType(ordersCourier.getPhone(), UserTypeEnum.MEMBER.getCode());
                String message="有订单申请退款请审核";
                //根据用户ID查询普通用户的别名
                UserAlias userAlias=userAliasService.selectMemberUserAliasByUserId(userId);
                if(null==userAlias){
                    throw new CustomException("用户别名为空");
                }
                //极光推送消息
                JPushExtraModel extra=new JPushExtraModel();
                extra.setCode("1019");
                extra.setArg(ordersGoodsIdsStr);
                extra.setIsReturn(PageTurnTypeEnum.APP.getValue());
                messagePushService.JPushMessage(userAlias,message,extra);


                //保存消息记录到数据库
                UserMessage userMessage = new UserMessage();
                userMessage.setUserId(userId);
                userMessage.setMessageType(MessageTypeEnum.团长审核.getValue());
                userMessage.setFkId(Long.valueOf(ordersGoodsIdsStr));
                userMessage.setFkMark("商品退款通知");
                String message2 = "尊敬的团长，您的有新的退单申请";
                userMessage.setStatusCode(OrdersStatusCodeEnum.团长有新的退单申请.getCode());
                userMessage.setFkContent(message2);
                userMessage.setCreateTime(DateUtils.getNowDate());
                int rows=messageService.insertUserMessage(userMessage);
                if(rows<1){
                    log.info("发送站内信息失败！");
                }
            } catch (Exception e) {
                log.error("orderSingleItemRefund()",e);
            }
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw  new CustomException(e.getMessage());
        }
        return  true;
    }

    private  UserAccountRecordOrderSingleItem  checkUserAccountRecordOrderSingleItem(SingleItemRefundDTO dto){
        String returnType=dto.getReturnType();
        if (StringUtils.isEmpty(returnType)){
            throw  new CustomException("退款类型不能为空");
        }
        String reason=dto.getReason();
        if (StringUtils.isEmpty(reason)){
            throw  new CustomException("理由不能为空");
        }
        String description= dto.getDescription();

        if (StringUtils.isEmpty(description)){
            throw  new CustomException("说明不能为空");
        }
        String photo=dto.getPhoto();
        if (StringUtils.isEmpty(photo)){
            throw  new CustomException("图片不能为空");
        }
        String payment=dto.getPayment();
        if (StringUtils.isEmpty(payment)){
            throw  new CustomException("金额不能为空");
        }

        String phonenumber=dto.getPhonenumber();
        if (StringUtils.isEmpty(phonenumber)){
            throw  new CustomException("电话号码不能为空");
        }
        Long userId=dto.getUserId();
        if (null ==userId){
            throw  new CustomException("userId 不能为空");
        }
        UserAccountRecordOrderSingleItem item =new UserAccountRecordOrderSingleItem();
        item.setUserId(userId);
        String ordersGoodsIdsStr=dto.getOrderGoodsIds();
        if (StringUtils.isEmpty(ordersGoodsIdsStr)){
            throw  new CustomException("ids不能为空");
        }
        String[]  ordersGoodsIds=ordersGoodsIdsStr.split(",");
        if (null ==ordersGoodsIds || ordersGoodsIds.length==0){
            throw  new CustomException("orderGoodsId 不能为空");
        }
        item.setMoney(new BigDecimal(payment).divide(new BigDecimal( ordersGoodsIds.length)).setScale(2,BigDecimal.ROUND_DOWN));
        item.setReturnType(returnType);
        item.setReason(reason);
        item.setDescription(description);
        item.setPhoto(photo);
        item.setPhonenumber(phonenumber);
        item.setMessageId(IdUtil.getSnowflake(1L,1L).nextId());
        return  item;
    }
    @Override
    public List<UserAccountRecordOrderSingleItemVO> listSysUserAccountRecordOrderSingleItemVO(SysUserAccountRecordOrderSingleItemDTO dto) {
        PageHelper.startPage(dto.getPageNum(),dto.getPageSize());
        List<UserAccountRecordOrderSingleItemVO> list=userAccountRecordOrderSingleItemMapper.listSysUserAccountRecordOrderSingleItemVO(dto);
        return list;
    }

    @Override
    public boolean refuse(Long id) {
        UserAccountRecordOrderSingleItem item=userAccountRecordOrderSingleItemMapper.selectByPrimaryKey(id);
        if (null ==item){
            throw  new CustomException("找不到这条记录");
        }
        Long  orderGoodsId=item.getOrderGoodsId();
        boolean bl= ordersGoodsService.sigleItemRefundRefuse(orderGoodsId);
        if (bl ==false){
            throw  new CustomException("操作失败");
        }
        MessageGoodsRefundMessageDTO refundMessageDTO=new MessageGoodsRefundMessageDTO();
        refundMessageDTO.setType(MQTypeEnum.GOODS_REFUND_MESSAGE_JPUSH.getType());
        refundMessageDTO.setOrdersGoodsId(orderGoodsId);
        refundMessageDTO.setSuccess(false);
        mqSendUtils.sendAsynMessage(refundMessageDTO);
        return true;
    }

    @Override
    public boolean agree(Long id) {
        UserAccountRecordOrderSingleItem item=userAccountRecordOrderSingleItemMapper.selectByPrimaryKey(id);
        if (null ==item){
            throw  new CustomException("找不到这条记录");
        }
        Long  orderGoodsId=item.getOrderGoodsId();
        boolean bl= ordersGoodsService.sigleItemRefundAgree(orderGoodsId);
        if (bl ==false){
            throw  new CustomException("操作失败");
        }
        String ordersNo=item.getOrderNo();
        Orders orders=ordersService.selectOrdersByOrdersNo(ordersNo);
        if (null == orders){
            throw  new CustomException("orders 订单不存在");
        }
        String payType=orders.getPayType();
        if (StringUtils.isEmpty(payType)){
            throw  new CustomException("payType 是空");
        }
        if (!(PayTypeEnum.ALIPAY.getCode().equals(payType)||PayTypeEnum.WXPAY.getCode().equals(payType))){
            throw  new CustomException("退款只支持微信支付宝");
        }

        Long messageId=item.getMessageId();
        Long userId=item.getUserId();
        BigDecimal money=item.getMoney();
        MessageOrderSingleltemDTO messageOrderSingleltemDTO=new MessageOrderSingleltemDTO();
        messageOrderSingleltemDTO.setMessageId(messageId);
        messageOrderSingleltemDTO.setUserId(userId);
        messageOrderSingleltemDTO.setMoney(money.toString());
        messageOrderSingleltemDTO.setType(MQTypeEnum.SINGLE_LTEM_REFUND_ACCOUNT.getType());
        messageOrderSingleltemDTO.setOrderNo(ordersNo);
        messageOrderSingleltemDTO.setOrdersGoodsId(orderGoodsId);
        mqSendUtils.sendAsynMessage(messageOrderSingleltemDTO);

        MessageGoodsRefundMessageDTO refundMessageDTO=new MessageGoodsRefundMessageDTO();
        refundMessageDTO.setType(MQTypeEnum.GOODS_REFUND_MESSAGE_JPUSH.getType());
        refundMessageDTO.setOrdersGoodsId(orderGoodsId);
        refundMessageDTO.setSuccess(true);
        mqSendUtils.sendAsynMessage(refundMessageDTO);
        return true;
    }

    @Override
    public String getOrderSingleItemRefundOrderNo(SingleItemRefundDTO dto) {
        boolean bl=orderSingleItemRefund(dto);
        if (bl==false){
            throw  new CustomException("退款失败，稍后再试");
        }
        String orderNo= dto.getOrderNo();
        return orderNo;
    }

    @Override
    public boolean insertUserAccountRecordOrderSingleItems(List<UserAccountRecordOrderSingleItem> items) {
        try{
            boolean bl=userAccountRecordOrderSingleItemMapper.insertList(items)>=1;
            if (bl==false){
                throw  new CustomException("退款失败，稍后再试");
            }
            return true;
        }catch (Exception e){
            throw  new CustomException("退款失败，稍后再试");
        }

    }

    @Override
    public boolean orderSingleItemRefunds(SingleItemRefundDTO dto) {

        return false;
    }

    @Override
    public  UserAccountRecordOrderSingleItem getUserAccountRecordOrderSingleItem(Long orderGoodsId) {
        Example example=new Example(UserAccountRecordOrderSingleItem.class);
        example.createCriteria()
                .andEqualTo("status",0)
                .andEqualTo("orderGoodsId",orderGoodsId)
                .andEqualTo("delFlag",0);
        return  getUserAccountRecordOrderSingleItem(example);
    }

    @Override
    public boolean deleteOrderSingleItem(UserAccountRecordOrderSingleItem item) {
        Long id=item.getId();
        if (null == id){
            throw  new CustomException("id 不能为空");
        }
        UserAccountRecordOrderSingleItem singleItem=userAccountRecordOrderSingleItemMapper.selectByPrimaryKey(id);
        if (null  ==singleItem){
            throw  new CustomException("singleItem 无数据");
        }
        Integer singleType=singleItem.getSingleType();
        if (singleType==1){
            throw  new CustomException("没有受理无法删除");
        }
        UserAccountRecordOrderSingleItem userAccountRecordOrderSingleItem=new UserAccountRecordOrderSingleItem();
        userAccountRecordOrderSingleItem.setId(id);
        userAccountRecordOrderSingleItem.setDelFlag(1);
        return userAccountRecordOrderSingleItemMapper.updateByPrimaryKeySelective(userAccountRecordOrderSingleItem)>=1;
    }

    @Override
    public boolean cancelOrderSingleItem(UserAccountRecordOrderSingleItem item) {
        Long id=item.getId();
        if (null == id){
            throw  new CustomException("id 不能为空");
        }
        UserAccountRecordOrderSingleItem singleItem=userAccountRecordOrderSingleItemMapper.selectByPrimaryKey(id);
        if (null  ==singleItem){
            throw  new CustomException("singleItem 无数据");
        }
        Integer singleType=singleItem.getSingleType();
        if (singleType!=1){
            throw  new CustomException("已经受理无法取消");
        }
        Long  orderGoodsId=singleItem.getOrderGoodsId();
        UserAccountRecordOrderSingleItem userAccountRecordOrderSingleItem=new UserAccountRecordOrderSingleItem();
        userAccountRecordOrderSingleItem.setId(id);
        userAccountRecordOrderSingleItem.setDelFlag(1);
        TransactionStatus transactionStatus=dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            boolean bl=ordersGoodsService.updateOrdersGoodsCancel(orderGoodsId);
            if (bl==false){
                throw  new CustomException("取消失败");
            }
            bl=userAccountRecordOrderSingleItemMapper.updateByPrimaryKeySelective(userAccountRecordOrderSingleItem)>=1;
            if (bl==false){
                throw  new CustomException("修改状态");
            }
            dataSourceTransactionManager.commit(transactionStatus);
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw  new CustomException(e.getMessage());
        }
        return true;
    }

    @Override
    public ReturnOrdersGoodsVO getReturnOrdersGoodsVO(Long orderGoodsId) {

        return userAccountRecordOrderSingleItemMapper.getReturnOrdersGoodsVO(orderGoodsId);
    }

    @Override
    public BigDecimal getSumReturnMoney(String orderNo) {
        BigDecimal bigDecimal=BigDecimal.ZERO;

        List<UserAccountRecordOrderSingleItem>  list= listUserAccountRecordOrderRefundSingleItem(orderNo);
        if (null == list || list.isEmpty()){
            return  bigDecimal;
        }
        for (UserAccountRecordOrderSingleItem item : list) {
            bigDecimal=bigDecimal.add(item.getMoney());
        }
        return  bigDecimal;
    }

    @Override
    public boolean updateRefundResult(UserAccountRecordOrderSingleItem item) {
        String orderNo=item.getOrderNo();
        if (StringUtils.isEmpty(orderNo)){
            throw  new CustomException("订单号不能为空");
        }
        Long orderGoodsId=item.getOrderGoodsId();
        if (null ==orderGoodsId){
            throw  new CustomException("goodsId不能为空");
        }
        Example example =new Example(UserAccountRecordOrderSingleItem.class);
        example.createCriteria()
                .andEqualTo("orderNo",orderNo)
                .andEqualTo("orderGoodsId",orderGoodsId);

        return userAccountRecordOrderSingleItemMapper.updateByExampleSelective(item,example)>0;
    }

    private List<UserAccountRecordOrderSingleItem> listUserAccountRecordOrderSingleItem(String orderNo){
        Example example=new Example(UserAccountRecordOrderSingleItem.class);
        example.createCriteria()
                .andEqualTo("status",0)
                .andEqualTo("orderNo",orderNo)
                .andEqualTo("status",0)
                .andEqualTo("delFlag",0);

        List<UserAccountRecordOrderSingleItem> userAccountRecordOrderSingleItems =userAccountRecordOrderSingleItemMapper.selectByExample(example);
        return  userAccountRecordOrderSingleItems;
    }
    private List<UserAccountRecordOrderSingleItem> listUserAccountRecordOrderRefundSingleItem(String orderNo){
        Example example=new Example(UserAccountRecordOrderSingleItem.class);
        example.createCriteria()
                .andEqualTo("status",0)
                .andEqualTo("delFlag",0)
                .andEqualTo("orderNo",orderNo)
                .andEqualTo("singleType",2)
                .andEqualTo("delFlag",0);
        List<UserAccountRecordOrderSingleItem> userAccountRecordOrderSingleItems =userAccountRecordOrderSingleItemMapper.selectByExample(example);
        return  userAccountRecordOrderSingleItems;
    }

    private  UserAccountRecordOrderSingleItem getUserAccountRecordOrderSingleItem(Example example){

      return    userAccountRecordOrderSingleItemMapper.selectOneByExample(example);
    }

    @Override
    public GiftReturn getGiftReturnByUserId(){
        return userAccountRecordOrderSingleItemMapper.getGiftReturnByUserId(ApiUtils.getUserId());
    }

    @Override
    public List<CourierRefundOrdersVO> refundListByCourierId(Long courierId,String refundAplStatus) {
        return ordersGoodsService.selectCourierRefundOrdersVOListByCourierId(courierId,refundAplStatus);
    }

    @Override
    public boolean updateRefundOrdesGoodsStatus(Long ordersGoodsId, String refundAplStatus) {
        return ordersGoodsService.updateRefundAplStatusByordersId(ordersGoodsId, refundAplStatus);
    }
}
